/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sd_proj1.mainProgram;

import sd_proj1.interfaces.ICustomer;
import sd_proj1.interfaces.ICustomerFifo;

/**
 *
 * @author Pedro Costa Correia - 32795
 * @author Valter Pedro Lopes Vicente - 39360
 */
class Customer extends Thread {

	/**
	 *  Identificação do cliente.
	 *
	 *    @serialField customerId
	 */
	private int customerId;
	/*
	 *  Instanciação da interface do cliente implementada no monitor da loja.
	 *
	 *    @serialField store
	 */
	private ICustomer store;
	/**
	 *  Instanciação da interface do cliente implementada no estado geral.
	 *
	 *    @serialField general
	 */
	private ICustomerFifo general;

	/**
	 *  Instanciação do thread do cliente.
	 *
	 *    @param customerId identificação do cliente.
	 * @param store Interface do cliente associada ao monitor da loja.
	 * @param general Interface do cliente associada ao estado geral.
	 */
	public Customer(int customerId, ICustomer store, ICustomerFifo general) {
		this.customerId = customerId;
		this.store = store;
		this.general = general;
	}

	/**
	 * Ciclo de vida da thread do cliente.
	 */
	@Override
	public void run() {
		int ng;                              /* number of selected goods */
		while (!store.endOperCustomer(customerId)) {
			while (true) {
				livingNormalLife();						  /* the customer minds his own business */
				store.goShopping(customerId);                  /* the customer decides to visit the handicraft shop */
				if (store.isDoorOpen()) /* the customer checks if the shop door is open */ {
					break;                                                    /* it is */
				} else {
					if (store.isDonaIsDead()) {
						break;
					} else {
						tryAgainLater();       /* it is not, the customer goes back to perform his daily chores */
					}
				}
			}
			if (!store.isDonaIsDead()) {
				store.enterShop(customerId);        /* the customer enters the shop */

				ng = store.perusingAround(customerId);  /* the customer inspects the offer in display
				and eventually picks up some goods */

				if (ng != 0) {
					general.addRequestCustomer(customerId);
					store.iWantThis(customerId, ng);             /* the customer queues by the counter
					to pay for the selected goods */
				}
				store.exitShop(customerId);                           /* the customer leaves the shop */
			}
		}
	}

	/**
	 *  O cliente vivendo a vida normal (operação interna).
	 */
	private void livingNormalLife() {
		try {
			sleep((long) (1 + 40 * Math.random()));
		} catch (InterruptedException e) {
		}
	}

	/**
	 *  O cliente volta mais tarde à store (operação interna).
	 */
	private void tryAgainLater() {
		try {
			sleep((long) (1 + 10 * Math.random()));
		} catch (InterruptedException e) {
		}
	}
}
